﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WIA;
using System.IO;
using WinForms = System.Windows.Forms;
using ShoeBoxScan.Properties;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Controls.Primitives;



namespace ShoeBoxScan {
  /// <summary>
  /// Interaction logic for Window1.xaml
  /// </summary>
  public partial class MainWindow : Window {
    public MainWindow( ) {
      InitializeComponent( );
    }



    public ImageSource MainSourceImage {
      get {
        return ( ImageSource )GetValue( MainSourceImageProperty );
      }
      set {
        SetValue( MainSourceImageProperty, value );
      }
    }

    // Using a DependencyProperty as the backing store for MainSourceImage.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MainSourceImageProperty =
        DependencyProperty.Register( "MainSourceImage", typeof( ImageSource ), typeof( MainWindow ), new UIPropertyMetadata( new BitmapImage( new Uri( "NoScannedImage.png", UriKind.Relative ) ) ) );



    WIA.ImageFile wiaImage = null;

    private void btnScanNow_Click( object sender, RoutedEventArgs e ) {
      ImageProcess i = new ImageProcess( );
      FilterInfos f = i.FilterInfos;
      foreach( FilterInfo fi in f ) {
        Debug.WriteLine( fi.Name + " " + fi.Description + " " + fi.FilterID );
      }


      CommonDialogClass wiaDiag = new CommonDialogClass( );
      wiaImage = null;

      try {
        wiaImage = wiaDiag.ShowAcquireImage(
                WiaDeviceType.ScannerDeviceType,
                WiaImageIntent.ColorIntent,
                WiaImageBias.MaximizeQuality,
                WIA.FormatID.wiaFormatJPEG, false, true, false );
      }
      catch( COMException ex ) {
        if( ex.ErrorCode == -2145320939 ) {
          System.Windows.MessageBox.Show( "Error retrieving a list of scanners. Is your scanner or multi-function printer turned on?", "No scanner found!", MessageBoxButton.OK );
        }
      }

      if( wiaImage != null ) {

        WIA.Vector vector = wiaImage.FileData;
        if( vector != null ) {
          byte[ ] bytes = vector.get_BinaryData( ) as byte[ ];
          if( bytes != null ) {
            var ms = new MemoryStream( bytes );
            imgScan.Source = BitmapFrame.Create( ms );
          }
        }
      }

      ////find the list of image devices
      //CommonDialogClass imgDilagoueClass = new CommonDialogClass();
      //Device d = imgDilagoueClass.ShowSelectDevice(WiaDeviceType.ScannerDeviceType, true, true);
      //if (d != null)
      //{ 
      //    //save the device ID
      //}

      //DeviceManagerClass dmc = new DeviceManagerClass();
      //foreach (DeviceInfo info in dmc.DeviceInfos)
      //{
      //    if (info.DeviceID == d.DeviceID)
      //    {
      //        d = info.Connect();
      //        break;
      //    }
      //}


      //Item item = d.ExecuteCommand(CommandID.wiaCommandSynchronize);

      //foreach (string format in item.Formats)
      //{
      //    if (format == "test")
      //    {
      //        WIA.ImageFile imagefile = item.Transfer(format) as WIA.ImageFile;
      //        //string filename = GetFreeFileName();
      //        //if (string.IsNullOrEmpty(filename) == false)
      //        //{
      //        //    imagefile.SaveFile(filename);
      //        //}
      //        //this.picLastImage.Load(filename);
      //        //return filename;
      //    }
      //}

      //scanner dialogue

      //acquire image

      //Window Image Acquisition (WIA)


    }

    private void ChooseFolder_Click( object sender, RoutedEventArgs e ) {
      var fd = new WinForms.FolderBrowserDialog( );
      var result = fd.ShowDialog( );
      if( result != System.Windows.Forms.DialogResult.Cancel ) {
        selectedFolder.Text = fd.SelectedPath;
        Settings.Default.Save( );
      }
      else {
        Settings.Default.Reload( );
      }

    }

    private void selectedFolder_MouseDoubleClick( object sender, MouseButtonEventArgs e ) {
      ChooseFolder_Click( sender, null );
    }

    private void SaveAll_Click( object sender, RoutedEventArgs e ) {
      //selectedFolder.GetBindingExpression(System.Windows.Controls.TextBox.TextProperty).UpdateSource();
      //startingFileName.GetBindingExpression(System.Windows.Controls.TextBox.TextProperty).UpdateSource();

      var selectedFolderText = selectedFolder.Text.Trim( );
      if( selectedFolderText.Length == 0 ) {
        System.Windows.MessageBox.Show( "Please select a folder to save your photos into and try again.", "Please select a folder", MessageBoxButton.OK );
        ChooseFolder_Click( null, null );
        selectedFolderText = selectedFolder.Text.Trim( );
      }
      if( Directory.Exists( selectedFolderText ) ) {
        int currentImage = 0;
        string newFileName = System.IO.Path.Combine( selectedFolder.Text, FindNextImageFileNameIn( selectedFolder.Text, startingFileName.Text, ref currentImage ) );
        wiaImage.SaveFile( newFileName );
        System.Windows.MessageBox.Show( String.Format( "TODO: DO SAVE TO {0}", selectedFolderText ) );
      }
      else {
        System.Windows.MessageBox.Show( String.Format( "The folder {0} doesn't exist? Please select a folder to save your photos into and try again.", selectedFolderText ), "Please select a folder", MessageBoxButton.OK );
        ChooseFolder_Click( null, null );
        selectedFolderText = selectedFolder.Text.Trim( );
      }

    }

    private string FindNextImageFileNameIn( string folder, string startingFile, ref int number ) {
      while( true ) {
        string filename = System.IO.Path.Combine( folder, startingFile + number.ToString( ) );
        if( File.Exists( filename ) == false ) {
          number = number + 1;
          return filename;
        }
      }

    }

    private void Window_Closing( object sender, System.ComponentModel.CancelEventArgs e ) {
      selectedFolder.GetBindingExpression( System.Windows.Controls.TextBox.TextProperty ).UpdateSource( );
      startingFileName.GetBindingExpression( System.Windows.Controls.TextBox.TextProperty ).UpdateSource( );
      Settings.Default.Save( );
    }

    private void Window_Loaded( object sender, RoutedEventArgs e ) {


      if( String.IsNullOrEmpty( Settings.Default.SelectedFolder ) ) {
        Settings.Default.SelectedFolder = Environment.GetFolderPath( Environment.SpecialFolder.MyPictures );
        Settings.Default.Save( );
      }
      selectedFolder.GetBindingExpression( System.Windows.Controls.TextBox.TextProperty ).UpdateSource( );
      startingFileName.GetBindingExpression( System.Windows.Controls.TextBox.TextProperty ).UpdateSource( );
    }

    private void Window_MouseLeftButtonDown( object sender, MouseButtonEventArgs e ) {
      if( e.ButtonState == MouseButtonState.Pressed )
        this.DragMove( );
    }

    private void button1_Click( object sender, RoutedEventArgs e ) {
      /*
       *   <ContentControl Name="DesignerItem"
             Width="100"
             Height="100"
             Canvas.Top="100"
             Canvas.Left="100"
             Style="{StaticResource DesignerItemStyle}">
              <Rectangle IsHitTestVisible="False" x:Name="blue" Fill="Blue" Opacity="0.1"/>
          </ContentControl>
       */

      ContentControl c = new ContentControl( );
      c.Width = 100;
      c.Height = 100;
      c.Style = Resources[ "DesignerItemStyle" ] as Style;
      var r = new Rectangle( );
      r.Fill = Brushes.Green;
      r.Opacity = 0.3;
      r.IsHitTestVisible = false;


      c.Content = r;
      c.Tag = "2";
      DesignerCanvas.Children.Add( c );
      Canvas.SetTop( c, 100 );
      Canvas.SetLeft( c, 100 );
      Selector.SetIsSelected( c, true );

      c.RenderTransform = new RotateTransform {
        Angle = 25
      };

      //doesnt work :/ i only get the unrotated bounding box
      var t = c.TransformToAncestor( DesignerCanvas ).TransformBounds( new Rect( 0, 0, c.Height, c.Width ) );

      CroppedBitmap cb = new CroppedBitmap( ( BitmapSource )MainSourceImage, new Int32Rect( ( int )Canvas.GetLeft( c ), ( int )Canvas.GetTop( c ), ( int )t.Width, ( int )t.Height ) );

      ////var rtb = new RenderTargetBitmap( 100, 100, 96, 96, PixelFormats.Default );
      ////rtb.Render( i );

      var u = new UserImage( );
      u.SetCanvasTop( 200 );
      u.SetCanvasLeft( 200 );

      u.GetRotationTransform( ).Angle = 45;
      var o = new RotateTransform { Angle = 25 };

      
      DesignerCanvas.Children.Add( u );
      
      u.InputSource = MainSourceImage as BitmapSource;

      testImage.Source = u.OutputSource;

      //this should all be databound to the adorner
    }

    private void button2_Click( object sender, RoutedEventArgs e ) {
      System.Windows.Forms.OpenFileDialog o = new System.Windows.Forms.OpenFileDialog( );
      o.ShowDialog( );
      MainSourceImage = new BitmapImage( new Uri( o.FileName ) );

    }
  }

  public static class ShoeExtensions {

    public static RotateTransform GetRotationTransform( this UIElement dp ) {
      if( dp.RenderTransform == null || !( dp.RenderTransform is RotateTransform ) )
        dp.RenderTransform = new RotateTransform( );
      
      return dp.RenderTransform as RotateTransform;
    }

    public static double GetCanvasTop( this UIElement dp ) {
      return Canvas.GetTop( dp );
    }

    public static void SetCanvasTop( this UIElement dp, double value ) {
      Canvas.SetTop( dp, value );
    }

    public static double GetCanvasLeft( this UIElement dp ) {
      return Canvas.GetLeft( dp );
    }

    public static void SetCanvasLeft( this UIElement dp, double value ) {
      Canvas.SetLeft( dp, value );
    }

  }
}

